package com.silverhaze.diamond.client.ui.dialogs;

import com.silverhaze.commons.db.datasource.ObjectEntity;
import com.silverhaze.commons.helpers.CommonUIHelper;
import com.silverhaze.diamond.common.entity.BrokenDetail;
import com.silverhaze.diamond.common.entity.CountedDetail;
import com.silverhaze.diamond.common.entity.Detail;
import com.silverhaze.diamond.common.entity.UsedDetail;
import com.silverhaze.diamond.client.data.SpecificData;
import com.silverhaze.diamond.client.data.dao.DAOLocator;
import com.silverhaze.diamond.client.ui.UIHelper;
import com.silverhaze.diamond.client.ui.table.DetailsTable;
import com.silverhaze.diamond.client.ui.table.model.CountedDetailsTableModel;
import com.silverhaze.diamond.client.ui.table.model.DetailsTableModel;
import com.silverhaze.diamond.client.resources.ServiceResourceContainer;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * SystemUser: Babanin
 * Date: 09.07.2008
 * Time: 18:08:22
 */
public class DetailSelectorDialog extends AbstractDialog {

    private Detail detail;
    private List<CountedDetail> usedDetailsList;
    private List<CountedDetail> selectedDetails;
    private List<CountedDetail> newDetails;
    private DialogConnector dialogConnector;
    private Class detailClazz;

    public DetailSelectorDialog(Frame owner) {
        super(null, "Select details", true);

        initView();
    }

    public DetailSelectorDialog(DialogConnector dialogConnector, List<CountedDetail> selectedDetails, Class detailClazz) {
        super(null, "Выбрать детали", true);

        setIconImage(ServiceResourceContainer.SERVICE.getImage());
        this.selectedDetails = selectedDetails;
        this.dialogConnector = dialogConnector;
        this.detailClazz = detailClazz;

        initView();
        setLocationRelativeTo(UIHelper.getMainFrame());
    }

    private void initView() {
        setTitle("Выбрать детали");
        setLayout(new BorderLayout());

        newDetails = new ArrayList<CountedDetail>();
        usedDetailsList = new ArrayList<CountedDetail>(checkSelectedWithAvailable(selectedDetails,
                DAOLocator.getInstance().getDetails()));

        final CountedDetailsTableModel countedDetailsTableModel = new CountedDetailsTableModel(usedDetailsList);
        final JTable usedDetails = new JTable(countedDetailsTableModel);

        final JButton addBtn = new JButton(new AbstractAction("Выбрать") {
            public void actionPerformed(ActionEvent e) {
                for (CountedDetail countedDetail : usedDetailsList) {
                    if (countedDetail.getDetail().equals(detail)) {
                        countedDetail.setQuantity(countedDetail.getQuantity() + 1);
                        countedDetailsTableModel.fillData(usedDetailsList);
                        return;
                    }
                }

                CountedDetail usedDetail = null;
                if (detailClazz.equals(BrokenDetail.class)) {
                    usedDetail = new BrokenDetail();
                } else if (detailClazz.equals(UsedDetail.class)) {
                    usedDetail = new UsedDetail();
                }

                usedDetail.setDetail(detail);
                usedDetail.setQuantity(1);

                newDetails.add(usedDetail);
                usedDetailsList.add(usedDetail);
                countedDetailsTableModel.fillData(usedDetailsList);
            }
        });
        addBtn.setEnabled(false);


        final DetailsTableModel detailsTableModel = new DetailsTableModel();
        final JTable details = new DetailsTable(detailsTableModel);
        details.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                int selectedRow = details.getSelectedRow();

                if (selectedRow >= 0 && selectedRow < detailsTableModel.getRowCount()) {
                    detail = detailsTableModel.getObjectAtRow(selectedRow);
                    addBtn.setEnabled(true);
                }
            }
        });

        final JButton createBtn = new JButton(new AbstractAction("Добавить") {
            public void actionPerformed(ActionEvent e) {
                DetailDialog.createDetail(null, new DialogConnector() {
                    public void objectSelected(Object o) {
                        detail = (Detail) o;

                        for (CountedDetail countedDetail : usedDetailsList) {
                            if (countedDetail.getDetail().equals(detail)) {
                                countedDetail.setQuantity(countedDetail.getQuantity() + 1);
                                countedDetailsTableModel.fillData(usedDetailsList);
                                return;
                            }
                        }

                        CountedDetail usedDetail = null;
                        if (detailClazz.equals(BrokenDetail.class)) {
                            usedDetail = new BrokenDetail();
                        } else if (detailClazz.equals(UsedDetail.class)) {
                            usedDetail = new UsedDetail();
                        }

                        usedDetail.setDetail(detail);
                        usedDetail.setQuantity(1);

                        newDetails.add(usedDetail);
                        usedDetailsList.add(usedDetail);
                        countedDetailsTableModel.fillData(usedDetailsList);

                        details.setModel(new DetailsTableModel());
                    }
                });
            }
        });

        JScrollPane detailsScrollPane = new JScrollPane(details);
        detailsScrollPane.setPreferredSize(new Dimension(400, 200));

        JScrollPane usedDetailsScrollPane = new JScrollPane(usedDetails);
        usedDetailsScrollPane.setPreferredSize(new Dimension(400, 200));

        JLabel qLabel = new JLabel("Количество: ");
        final JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000, 1));
        final JButton setBtn = new JButton(new AbstractAction("Установить") {
            public void actionPerformed(ActionEvent e) {
                final int selectedRow = usedDetails.getSelectedRow();
                CountedDetail countedDetail = countedDetailsTableModel.getObjectAtRow(selectedRow);
                if (countedDetail != null) {
                    countedDetail.setQuantity(Integer.parseInt(spinner.getValue().toString()));
                    countedDetailsTableModel.fillData(usedDetailsList);
                    usedDetails.setRowSelectionInterval(selectedRow, selectedRow);
                }
            }
        });

        final JButton removeBtn = new JButton();
        removeBtn.setAction(new AbstractAction("Удалить") {
            public void actionPerformed(ActionEvent e) {
                CountedDetail countedDetail = countedDetailsTableModel.getObjectAtRow(usedDetails.getSelectedRow());
                if (countedDetail != null) {
                    usedDetailsList.remove(countedDetail);
                    countedDetailsTableModel.fillData(usedDetailsList);
                }
                if (countedDetailsTableModel.getRowCount() != 0) {
                    usedDetails.setRowSelectionInterval(0, 0);
                } else {
                    setBtn.setEnabled(false);
                    removeBtn.setEnabled(false);
                }
            }
        });

        usedDetails.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                setBtn.setEnabled(true);
                removeBtn.setEnabled(true);
            }
        });

        setBtn.setEnabled(false);
        removeBtn.setEnabled(false);

        final JTextField nameFilterField = new JTextField(10);

        nameFilterField.setText("*");
        nameFilterField.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                DetailsTableModel localTableModel = (DetailsTableModel) details.getModel();
                localTableModel.fillData(SpecificData.filterDetails(nameFilterField.getText(), DAOLocator.getInstance().getDetails()));
                localTableModel.fireTableDataChanged();
            }
        });

        Box selectDetailBox = CommonUIHelper.createVerticalBox(
                detailsScrollPane,
                2,
                CommonUIHelper.createHorizontalBox(new JLabel("Деталь: "), 2, nameFilterField, 2, addBtn, createBtn));
        selectDetailBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        Box selectedDetailBox = CommonUIHelper.createVerticalBox(
                usedDetailsScrollPane,
                2,
                CommonUIHelper.createHorizontalBox(qLabel, 2, spinner, 2, setBtn, 2, removeBtn)
        );
        selectedDetailBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        Box vBox = CommonUIHelper.createVerticalBox(
                CommonUIHelper.packInTitledPanel(selectDetailBox, BorderLayout.CENTER, " Выбрать детали "),
                5,
                CommonUIHelper.packInTitledPanel(selectedDetailBox, BorderLayout.CENTER, " Выбранные детали "));
        vBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        add(vBox, BorderLayout.CENTER);
        add(initializeOkCancelPanel(DialogType.EDIT), BorderLayout.PAGE_END);
        pack();
    }

    private List<CountedDetail> checkSelectedWithAvailable(List<? extends ObjectEntity> selectedDetails, List<ObjectEntity> details) {
        List<CountedDetail> result = new ArrayList<CountedDetail>();

        for (ObjectEntity e : selectedDetails) {
            CountedDetail usedDetail = (CountedDetail) e;

            if (details.contains(usedDetail.getDetail())) {
                result.add(usedDetail);
            }
        }

        return result;
    }

    protected void okPressed() {
        for (CountedDetail countedDetail : newDetails) {
            DAOLocator.getInstance().add(countedDetail);
        }

        dialogConnector.objectSelected(usedDetailsList);
        dispose();
    }

    public static void selectDetails(DialogConnector dialogConnector, List<CountedDetail> selectedDetails, Class detailClazz) {
        DetailSelectorDialog dialog = new DetailSelectorDialog(dialogConnector, selectedDetails, detailClazz);
        dialog.setVisible(true);
    }
}

